1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"1038.11">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px 'Lucida Grande'}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande'; min-height: 17.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0000bf}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Lucida Grande'}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px 'Lucida Grande'; min-height: 18.0px}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #0000bf}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
20 p
.p11
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
21 p
.p12
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Courier
; min-height: 17.0px}
22 p
.p13
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #3300d3}
23 p
.p14
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
24 p
.p15
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande'; color: #000000; min-height: 17.0px}
25 p
.p16
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000}
26 p
.p17
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
27 p
.p18
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #737373}
28 span
.s1
{color: #0000bf}
29 span
.s2
{color: #000000}
30 span
.s3
{font: 14.0px 'Lucida Grande'}
31 span
.s4
{font: 14.0px Courier
; color: #000000}
32 span
.s5
{font: 9.0px Monaco
}
33 span
.s6
{font: 12.0px Helvetica
; color: #000000}
34 span
.s7
{color: #3300d3}
35 span
.s8
{color: #4300ff}
36 span
.s9
{font: 9.0px Monaco
; color: #0000bf}
37 span
.s10
{font: 14.0px 'Lucida Grande'; color: #000000}
38 span
.s11
{color: #737373}
39 span
.Apple-tab-span
{white-space:pre
}
43 <p class=
"p1"><b>Writing SuperCollider Classes
<span class=
"Apple-converted-space"> </span></b></p>
44 <p class=
"p2"><br></p>
45 <p class=
"p3">For a basic tutorial on how standard object-orientated classes are composed, look elsewhere
<span class=
"Apple-converted-space"> </span></p>
46 <p class=
"p4">http://www.google.com/search?q=oop+class+tutorial
</p>
47 <p class=
"p2"><br></p>
48 <p class=
"p3">Note: Class definitions are statically compiled when you launch supercollider or
"recompile the library." This means that class definitions must be saved into a file with the extension .sc, in a disk location where supercollider looks for classes. Saving into the main class library (SCClassLibrary) is generally not recommended. It's preferable to use either the user or system extension directories.
</p>
49 <p class=
"p5"><br></p>
50 <p class=
"p6"><span class=
"s1">Platform
</span><span class=
"s2">.userExtensionDir;
<span class=
"Apple-converted-space"> </span></span>// Extensions available only to your user account
</p>
51 <p class=
"p6"><span class=
"s1">Platform
</span><span class=
"s2">.systemExtensionDir;
<span class=
"Apple-converted-space"> </span></span>// Extensions available to all users on the machine
</p>
52 <p class=
"p5"><br></p>
53 <p class=
"p3">It is not possible to enter a class definition into an interpreter window and execute it.
</p>
54 <p class=
"p2"><br></p>
55 <p class=
"p2"><br></p>
56 <p class=
"p7"><b>Inheriting
<span class=
"Apple-converted-space"> </span></b></p>
57 <p class=
"p8"><br></p>
58 <p class=
"p9"><span class=
"Apple-tab-span"> </span>NewClass
<span class=
"s2"> :
</span>SomeSuperclass
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
59 <p class=
"p10"><br></p>
60 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
61 <p class=
"p12"><br></p>
62 <p class=
"p12"><br></p>
63 <p class=
"p3">Without specifying a superclass, Object is assumed as the default superclass.
<span class=
"Apple-converted-space"> </span></p>
64 <p class=
"p8"><br></p>
65 <p class=
"p6"><span class=
"s1"><span class=
"Apple-tab-span"> </span>NewClass
</span><span class=
"s2"> {
</span>// : Object is implied
</p>
66 <p class=
"p10"><br></p>
67 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
68 <p class=
"p12"><br></p>
69 <p class=
"p12"><br></p>
70 <p class=
"p7"><b>Methods
<span class=
"Apple-converted-space"> </span></b></p>
71 <p class=
"p8"><br></p>
72 <p class=
"p3"><b>class methods
</b> are specified with the asterix
</p>
73 <p class=
"p2"><br></p>
74 <p class=
"p11"><span class=
"s3"><span class=
"Apple-tab-span"> </span></span>*classMethod {
<span class=
"s1">arg
</span> argument;
<span class=
"Apple-converted-space"> </span></p>
75 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
76 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
77 <p class=
"p12"><br></p>
78 <p class=
"p3"><span class=
"Apple-tab-span"> </span>within the class method, the keyword
<span class=
"Apple-converted-space"> </span></p>
79 <p class=
"p12"><span class=
"Apple-tab-span"> </span></p>
80 <p class=
"p9"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>this
<span class=
"s2"><span class=
"Apple-converted-space"> </span></span></p>
81 <p class=
"p5"><br></p>
82 <p class=
"p3"><span class=
"Apple-tab-span"> </span>refers to the class.
<span class=
"Apple-converted-space"> </span></p>
83 <p class=
"p5"><br></p>
84 <p class=
"p3"><span class=
"Apple-tab-span"> </span>A class in smalltalk is itself an object.
<span class=
"Apple-converted-space"> </span>It is an instance of Class.
</p>
85 <p class=
"p2"><br></p>
86 <p class=
"p2"><br></p>
87 <p class=
"p3"><b>instance methods
</b> are specified :
</p>
88 <p class=
"p2"><br></p>
89 <p class=
"p11"><span class=
"s3"><span class=
"Apple-tab-span"> </span></span>instanceMethod {
<span class=
"s1">arg
</span> argument;
<span class=
"Apple-converted-space"> </span></p>
90 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
91 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
92 <p class=
"p12"><br></p>
93 <p class=
"p3"><span class=
"Apple-tab-span"> </span>within the instance method, the keyword
<span class=
"Apple-converted-space"> </span></p>
94 <p class=
"p12"><span class=
"Apple-tab-span"> </span></p>
95 <p class=
"p9"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>this
<span class=
"s2"><span class=
"Apple-converted-space"> </span></span></p>
96 <p class=
"p12"><br></p>
97 <p class=
"p3"><span class=
"Apple-tab-span"> </span>refers to the instance.
<span class=
"Apple-converted-space"> </span></p>
98 <p class=
"p2"><br></p>
99 <p class=
"p2"><br></p>
100 <p class=
"p2"><br></p>
101 <p class=
"p3">to
<b>return
</b> from the method use ^ (caret)
</p>
102 <p class=
"p2"><br></p>
103 <p class=
"p10"><br></p>
104 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someMethod {
<span class=
"Apple-converted-space"> </span></p>
105 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^returnObject
<span class=
"Apple-converted-space"> </span></p>
106 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
107 <p class=
"p12"><br></p>
108 <p class=
"p12"><br></p>
109 <p class=
"p3">multiple exit points also possible :
<span class=
"Apple-converted-space"> </span></p>
110 <p class=
"p2"><br></p>
111 <p class=
"p2"><br></p>
112 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someMethod {
<span class=
"s1">arg
</span> aBoolean;
<span class=
"Apple-converted-space"> </span></p>
113 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if(aBoolean,{
<span class=
"Apple-converted-space"> </span></p>
114 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^someObject
<span class=
"Apple-converted-space"> </span></p>
115 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>},{
<span class=
"Apple-converted-space"> </span></p>
116 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^someOtherObject
<span class=
"Apple-converted-space"> </span></p>
117 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>})
<span class=
"Apple-converted-space"> </span></p>
118 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
119 <p class=
"p12"><br></p>
120 <p class=
"p5"><br></p>
121 <p class=
"p3"><span class=
"Apple-tab-span"> </span>if no ^ is specified, the method will return the
<b>instance
</b>.
<span class=
"Apple-converted-space"> </span></p>
122 <p class=
"p3"><span class=
"Apple-tab-span"> </span>(and in the case of Class methods, will return the class)
<span class=
"Apple-converted-space"> </span></p>
123 <p class=
"p5"><br></p>
124 <p class=
"p3"><span class=
"Apple-tab-span"> </span>There is no such thing as returning void in Smalltalk.
</p>
125 <p class=
"p2"><br></p>
126 <p class=
"p2"><br></p>
127 <p class=
"p2"><br></p>
128 <p class=
"p7"><b>New Instance creation
<span class=
"Apple-converted-space"> </span></b></p>
129 <p class=
"p8"><br></p>
130 <p class=
"p3">Object.new will return to you a new object.
<span class=
"Apple-converted-space"> </span></p>
131 <p class=
"p3">when overriding the class method .new you must call the superclass, which in turn calls its superclass, up until Object.new is called and an object is actually created and its memory allocated.
</p>
132 <p class=
"p2"><br></p>
133 <p class=
"p6"><span class=
"Apple-tab-span"> </span>// this example adds no new functionality
<span class=
"Apple-converted-space"> </span></p>
134 <p class=
"p11"><span class=
"Apple-tab-span"> </span>*new {
<span class=
"Apple-converted-space"> </span></p>
135 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^
<span class=
"s1">super
</span>.new
<span class=
"Apple-converted-space"> </span></p>
136 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
137 <p class=
"p10"><br></p>
138 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// this is a normal constructor method
</p>
139 <p class=
"p11"><span class=
"Apple-tab-span"> </span>*new {
<span class=
"s1">arg
</span> arga,argb,argc;
<span class=
"Apple-converted-space"> </span></p>
140 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^
<span class=
"s1">super
</span>.new.init(arga,argb,argc)
<span class=
"Apple-converted-space"> </span></p>
141 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
142 <p class=
"p11"><span class=
"Apple-tab-span"> </span>init {
<span class=
"s1">arg
</span> arga,argb,argc;
</p>
143 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-converted-space"> </span></span>// do initiation here
</p>
144 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
145 <p class=
"p12"><br></p>
146 <p class=
"p3">In this case note that super.new called the method new on the superclass and returned a new object. subsequently we are calling the .init method on that object, which is an instance method.
<span class=
"Apple-converted-space"> </span></p>
147 <p class=
"p5"><br></p>
148 <p class=
"p3"><b>Warning:
</b>if the superclass also happened to call super.new.init it will have expected to call the .init method defined in that class (the superclass), but instead the message .init will find the implementation of the class that the object actually is, which is our new subclass.
<span class=
"Apple-converted-space"> </span>So you should use a unique method name like myclassinit if this is likely to be a problem.
</p>
149 <p class=
"p5"><br></p>
150 <p class=
"p3">One easy way to copy the arguments passed to the instance variables when creating a class is to use
<span class=
"s5">newCopyArgs
</span>.
<span class=
"Apple-converted-space"> </span>This method will copy the arguments to the instance variables in the order that the variables were defined in the class, starting the parent classes and working it's way down to the current class.
<span class=
"Apple-converted-space"> </span></p>
151 <p class=
"p5"><br></p>
152 <p class=
"p13"><span class=
"s6"><span class=
"Apple-tab-span"> </span></span>MyClass
<span class=
"s2">{
</span></p>
153 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s7">var
</span> <a,b,c;
</p>
154 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
155 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new {
<span class=
"s7">arg
</span> a,b,c;
<span class=
"Apple-converted-space"> </span></p>
156 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^
<span class=
"s7">super
</span>.newCopyArgs(a,b,c)
<span class=
"Apple-converted-space"> </span></p>
157 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
158 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
159 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
160 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
161 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>MyChildClass
<span class=
"s2"> :
</span>MyClass
<span class=
"s2">{
</span></p>
162 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s7">var
</span> <d;
</p>
163 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
164 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new {
<span class=
"s7">arg
</span> a,b,c,d;
<span class=
"Apple-converted-space"> </span></p>
165 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^
<span class=
"s7">super
</span>.newCopyArgs(a,b,c,d)
<span class=
"Apple-converted-space"> </span></p>
166 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
167 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
168 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
169 <p class=
"p10"><br></p>
170 <p class=
"p3">Over reliance on inheritance is usually a design flaw.
<span class=
"Apple-converted-space"> </span>Explore
"object composition" rather than trying to obtain all your powers through inheritance. Is your
"subclass" really some kind of
"superclass" or are you just trying to swipe all of daddy's methods ? Do a websearch for
<span class=
"Apple-converted-space"> </span>Design Patterns.
</p>
171 <p class=
"p5"><br></p>
172 <p class=
"p3">Class variables are accessible within class methods and in any instance methods.
<span class=
"Apple-converted-space"> </span></p>
173 <p class=
"p2"><br></p>
174 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"s1">classvar
</span> myClassvar;
</p>
175 <p class=
"p10"><br></p>
176 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span> myInstanceVar;
<span class=
"Apple-converted-space"> </span></p>
177 <p class=
"p12"><br></p>
178 <p class=
"p5"><br></p>
179 <p class=
"p3">For class initialization check
<a href=
"SC://initClass"><span class=
"s8">initClass
</span></a><span class=
"s8">.
</span></p>
180 <p class=
"p2"><br></p>
181 <p class=
"p7"><b>Overriding Methods (Overloading)
</b></p>
182 <p class=
"p2"><br></p>
183 <p class=
"p3">in order to change the behaviour of the superclass, often methods are overridden.
</p>
184 <p class=
"p3">note that an object looks always for the method it has defined first and then looks in the superclass.
</p>
185 <p class=
"p3">here
<span class=
"s9">NewClass
</span><span class=
"s5">.value(
2)
</span> will return
<span class=
"s9"> 6</span>, not
<span class=
"s9"> 4</span>:
<span class=
"Apple-converted-space"> </span></p>
186 <p class=
"p12"><br></p>
187 <p class=
"p9"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>Superclass
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
188 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
189 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>calculate {
<span class=
"s1">arg
</span> in; in *
2 }
</p>
190 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>value {
<span class=
"s1">arg
</span> in; ^
<span class=
"s1">this
</span>.calculate(in) }
</p>
191 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
192 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
193 <p class=
"p9"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>NewClass
<span class=
"s2"> :
</span>Superclass
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
194 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
195 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>calculate {
<span class=
"s1">arg
</span> in; in *
3 }
</p>
196 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
197 <p class=
"p12"><br></p>
198 <p class=
"p5"><br></p>
199 <p class=
"p5"><span class=
"Apple-converted-space"> </span></p>
200 <p class=
"p3">if the method of the superclass is needed, it can be called by
<b>super
</b>.
</p>
201 <p class=
"p12"><br></p>
202 <p class=
"p9"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>Superclass
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
203 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span> x;
</p>
204 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
205 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>init {
</p>
206 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>x =
5;
</p>
207 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
208 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
209 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
210 <p class=
"p9"><span class=
"s4"><span class=
"Apple-tab-span"> </span></span>NewClass
<span class=
"s2"> :
</span>Superclass
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
211 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span> y;
</p>
212 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>init {
<span class=
"Apple-converted-space"> </span></p>
213 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">super
</span>.init;
</p>
214 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>y =
6;
<span class=
"Apple-converted-space"> </span></p>
215 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
216 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
217 <p class=
"p12"><br></p>
218 <p class=
"p12"><br></p>
219 <p class=
"p12"><br></p>
220 <p class=
"p12"><br></p>
221 <p class=
"p7"><b>Getter Setter
<span class=
"Apple-converted-space"> </span></b></p>
222 <p class=
"p8"><br></p>
223 <p class=
"p3">Classic Smalltalk demands that variables are not accessible outside of the class or instance.
<span class=
"Apple-converted-space"> </span>A method must be added to explicitly give access:
<span class=
"Apple-converted-space"> </span></p>
224 <p class=
"p2"><br></p>
225 <p class=
"p2"><span class=
"Apple-tab-span"> </span></p>
226 <p class=
"p9"><span class=
"s10"><span class=
"Apple-tab-span"> </span></span>NewClass
<span class=
"s2"> :
</span>Superclass
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
227 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
228 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span> myVariable;
</p>
229 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
230 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>variable {
<span class=
"Apple-converted-space"> </span></p>
231 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^myVariable
<span class=
"Apple-converted-space"> </span></p>
232 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
233 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
234 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>variable_ {
<span class=
"s1">arg
</span> newValue;
<span class=
"Apple-converted-space"> </span></p>
235 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>myVariable = newValue;
<span class=
"Apple-converted-space"> </span></p>
236 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
237 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
238 <p class=
"p12"><br></p>
239 <p class=
"p3">These are referred to as getter and setter methods.
<span class=
"Apple-converted-space"> </span></p>
240 <p class=
"p2"><br></p>
241 <p class=
"p3">SC allows these methods to be easily added by adding
< or
><span class=
"Apple-converted-space"> </span></p>
242 <p class=
"p2"><br></p>
243 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span> <getMe,
>setMe,
<>getMeOrSetMe;
<span class=
"Apple-converted-space"> </span></p>
244 <p class=
"p12"><br></p>
245 <p class=
"p12"><br></p>
246 <p class=
"p3">you now have the methods:
<span class=
"Apple-converted-space"> </span></p>
247 <p class=
"p2"><br></p>
248 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someObject.getMe;
</p>
249 <p class=
"p10"><br></p>
250 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someObject.setMe_(value);
</p>
251 <p class=
"p12"><span class=
"Apple-tab-span"> </span></p>
252 <p class=
"p3">this also allows us to say:
</p>
253 <p class=
"p12"><br></p>
254 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someObject.setMe = value;
</p>
255 <p class=
"p10"><br></p>
256 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someObject.getMeOrSetMe_(
5);
</p>
257 <p class=
"p11"><span class=
"Apple-tab-span"> </span>someObject.getMeOrSetMe.postln;
<span class=
"Apple-converted-space"> </span></p>
258 <p class=
"p12"><br></p>
259 <p class=
"p10"><br></p>
260 <p class=
"p12"><br></p>
261 <p class=
"p3">a getter or setter method created in this fashion may
<span class=
"Apple-converted-space"> </span>be overridden in a subclass by manually writing the method
<span class=
"Apple-converted-space"> </span></p>
262 <p class=
"p3">setter methods should
<b>take only one argument
</b>to support both ways of expression consistently.
</p>
263 <p class=
"p3">eg.
<span class=
"Apple-converted-space"> </span><span class=
"s3"><span class=
"Apple-tab-span"> </span></span></p>
264 <p class=
"p11"><span class=
"Apple-tab-span"> </span>variable_ { arg newValue;
<span class=
"Apple-converted-space"> </span></p>
265 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>variable = newValue.clip(minval,maxval);
<span class=
"Apple-converted-space"> </span></p>
266 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-converted-space"> </span></p>
267 <p class=
"p10"><br></p>
268 <p class=
"p3">A setter method should always return the receiver. This is standard OOP practice (outside of SC as well). Do not return the new value from your setter.
</p>
269 <p class=
"p5"><br></p>
270 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>variable_ {
<span class=
"s1">arg
</span> newValue;
<span class=
"Apple-converted-space"> </span></p>
271 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>myVariable = newValue;
</p>
272 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^newValue
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// DO NOT DO THIS
</p>
273 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
274 <p class=
"p2"><br></p>
275 <p class=
"p2"><br></p>
276 <p class=
"p14"><b>External Method Files
</b></p>
277 <p class=
"p5"><br></p>
278 <p class=
"p3">Methods may be added to Classes in separate files.
<span class=
"Apple-converted-space"> </span>This is equivalent to Protocols in Objective-C.
<span class=
"Apple-converted-space"> </span>By convention, the file name starts with a lower case letter: the name of the method or feature that the methods are supporting.
</p>
279 <p class=
"p2"><br></p>
280 <p class=
"p3">Syntax:
</p>
281 <p class=
"p2"><br></p>
282 <p class=
"p11"><span class=
"Apple-tab-span"> </span>+
<span class=
"s1">Class
</span> {
</p>
283 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>newMethod {
</p>
284 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
285 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
286 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*newClassMethod {
</p>
287 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
288 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
289 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
290 <p class=
"p2"><br></p>
291 <p class=
"p2"><br></p>
292 <p class=
"p14"><b>Slotted classes
</b></p>
293 <p class=
"p5"><br></p>
294 <p class=
"p3">Classes defined with
<span class=
"s5">[slot]
</span><span class=
"Apple-converted-space"> </span>can use the syntax
<span class=
"s5">myClass[i]
</span>which will call
<span class=
"Apple-converted-space"> </span><span class=
"s5">myClass.at(i).
</span>This is usefull when defining classes that inherit from a Collection type class.
</p>
295 <p class=
"p2"><br></p>
296 <p class=
"p3">Syntax:
</p>
297 <p class=
"p15"><br></p>
298 <p class=
"p16"><span class=
"Apple-tab-span"> </span><span class=
"s7">MyClass
</span>[slot] {
</p>
299 <p class=
"p17"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
300 <p class=
"p16"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new{ ^
<span class=
"s7">super
</span>.new }
</p>
301 <p class=
"p17"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
302 <p class=
"p16"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
303 <p class=
"p17"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
304 <p class=
"p16"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>at{
<span class=
"s7">|i|
</span></p>
305 <p class=
"p16"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>(
<span class=
"s11">"Index "</span>++i).postln
<span class=
"Apple-converted-space"> </span></p>
306 <p class=
"p16"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-converted-space"> </span></p>
307 <p class=
"p17"><br></p>
308 <p class=
"p17"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
309 <p class=
"p17"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
310 <p class=
"p16"><span class=
"Apple-tab-span"> </span>}
</p>
311 <p class=
"p17"><span class=
"Apple-tab-span"> </span></p>
312 <p class=
"p17"><span class=
"Apple-tab-span"> </span></p>
313 <p class=
"p16"><span class=
"Apple-tab-span"> </span>a =
<span class=
"s7">MyClass
</span>();
</p>
314 <p class=
"p16"><span class=
"Apple-tab-span"> </span>a[
3];
</p>
315 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
316 <p class=
"p3">Defining a custom array of Points:
</p>
317 <p class=
"p5"><br></p>
318 <p class=
"p13"><span class=
"s6"><span class=
"Apple-tab-span"> </span></span>MyPointArray
<span class=
"s2">[slot] :
</span>RawArray
<span class=
"s2"> {
</span></p>
319 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
320 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>center { ^Point(*
<span class=
"s7">this
</span>.asArray.flop.collect{
<span class=
"s7">|item|
</span> item.sum / item.size } ) }
</p>
321 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
322 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>asArray{ ^
<span class=
"s7">this
</span>.collect{
<span class=
"s7">|elem|
</span> elem.asArray } }
</p>
323 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
324 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
325 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
326 <p class=
"p5"><br></p>
327 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
328 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
329 <p class=
"p14"><b>Printing custom messages to post window
</b></p>
330 <p class=
"p5"><br></p>
331 <p class=
"p3">By default when postln is called on an class instance the name of the class is printed in a post window.
<span class=
"Apple-converted-space"> </span>When
<span class=
"s5">postln
</span><span class=
"Apple-converted-space"> </span>or
<span class=
"s5">asString
</span> is called on a class instance, the class then calls
<span class=
"s5">printOn
</span> which can be overridden to obtain more useful information.
</p>
332 <p class=
"p2"><br></p>
333 <p class=
"p3">Syntax:
</p>
334 <p class=
"p2"><br></p>
335 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>MyTestPoint
<span class=
"s2"> {
</span></p>
336 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s7">var
</span> <x,
<y;
</p>
337 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
338 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new{
<span class=
"s7">|x,y|
</span> ^
<span class=
"s7">super
</span>.newCopyArgs(x,y) }
</p>
339 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
340 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>printOn {
<span class=
"s7">arg
</span> stream;
</p>
341 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>stream
<< <span class=
"s11">"MyTestPoint( "</span> << x
<< <span class=
"s11">", "</span> << y
<< <span class=
"s11">" )"</span>;
</p>
342 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
343 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
344 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
345 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
346 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
347 <p class=
"p11"><span class=
"Apple-tab-span"> </span>a =
<span class=
"s7">MyTestPoint
</span>(
2,
3);
</p>
348 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
349 <p class=
"p14"><b>Defining custom asCompileString behaviour
</b></p>
350 <p class=
"p5"><br></p>
351 <p class=
"p3">A call to
<span class=
"s5">asCompileString
</span>should return a string which when evaluated creates the exact same instance of the class. To define a custom behaviour one should either override
<span class=
"s5">storeOn
</span>or
<span class=
"s5">storeArgs
</span>.
<span class=
"Apple-converted-space"> </span></p>
352 <p class=
"p3"><span class=
"Apple-tab-span"> </span>The method
<span class=
"s5">storeOn
</span>should return the string that evaluated creates the instance of the current object.
</p>
353 <p class=
"p3"><span class=
"Apple-tab-span"> </span>The method
<span class=
"s5">storeArgs
</span>should return an array with the arguments to be passed to
<span class=
"s5">TheClass.new
</span>. In most cases this method can be used instead of
<span class=
"s5">storeOn.
</span></p>
354 <p class=
"p2"><br></p>
355 <p class=
"p3">Syntax:
</p>
356 <p class=
"p5"><br></p>
357 <p class=
"p3">either
</p>
358 <p class=
"p2"><br></p>
359 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>MyTestPoint
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
360 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s7">var
</span> <x,
<y;
</p>
361 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
362 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new{
<span class=
"s7">|x,y|
</span> ^
<span class=
"s7">super
</span>.newCopyArgs(x,y) }
</p>
363 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
364 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>storeOn {
<span class=
"s7">arg
</span> stream;
</p>
365 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>stream
<< <span class=
"s11">"MyTestPoint.new("</span> << x
<< <span class=
"s11">", "</span> << y
<< <span class=
"s11">")"</span>;
</p>
366 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
367 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
368 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-tab-span"> </span></p>
369 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
370 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"s7">MyTestPoint
</span>(
2,
3).asCompileString;
</p>
371 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
373 <p class=
"p2"><br></p>
374 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>MyTestPoint
<span class=
"s2"> {
<span class=
"Apple-converted-space"> </span></span></p>
375 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s7">var
</span> <x,
<y;
</p>
376 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
377 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new{
<span class=
"s7">|x,y|
</span> ^
<span class=
"s7">super
</span>.newCopyArgs(x,y) }
</p>
378 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
379 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>storeArgs {
<span class=
"s7">arg
</span> stream;
</p>
380 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>^[x,y]
</p>
381 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
382 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
383 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
<span class=
"Apple-tab-span"> </span></p>
384 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
385 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"s7">MyTestPoint
</span>(
2,
3).asCompileString;
<span class=
"Apple-tab-span"> </span></p>
386 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
387 <p class=
"p2"><br></p>
388 <p class=
"p7"><b>Tricks and Traps
<span class=
"Apple-converted-space"> </span></b></p>
389 <p class=
"p5"><br></p>
390 <p class=
"p3"><b>"Superclass not found..."</b></p>
391 <p class=
"p5"><br></p>
392 <p class=
"p3">In one given code file, you can only put classes that inherit from each Object, each other, and one external class.
<span class=
"Apple-converted-space"> </span>In other words, you can't inherit from two separate classes that are defined in separate files.
</p>
393 <p class=
"p5"><br></p>
394 <p class=
"p3">If you should happen to declare a variable in a subclass and use the same name as a variable declared in a superclass, you will find that both variables exist, but only the one in the object's actual class is accessible.
<span class=
"Apple-converted-space"> </span>You should not do that. This will at some point become an error worthy of compilation failure.
</p>
395 <p class=
"p5"><br></p>
396 <p class=
"p3"><b>Catching methods that are not explicitly defined
</b></p>
397 <p class=
"p5"><br></p>
398 <p class=
"p3">It is possible to catch calls to methods that are not explicitly defined in a Class by overriding
<span class=
"Apple-converted-space"> </span><span class=
"s5">doesNotUnderstand.
</span><span class=
"Apple-converted-space"> </span></p>
399 <p class=
"p5"><br></p>
400 <p class=
"p13"><span class=
"s6"><span class=
"Apple-tab-span"> </span></span>MyClass
<span class=
"s2"> {
</span></p>
401 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
402 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*new{ ^
<span class=
"s7">super
</span>.new }
</p>
403 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
404 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>doesNotUnderstand{
<span class=
"s7">arg
</span> selector...args;
</p>
405 <p class=
"p18"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>(
</span><span class=
"s7">this
</span><span class=
"s2">.class++
</span>" does not understand method "<span class=
"s2">++selector);
</span></p>
406 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
407 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s7">If
</span>(
<span class=
"s7">UGen
</span>.findRespondingMethodFor(selector).notNil){
</p>
408 <p class=
"p18"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>"But UGen understands this method"<span class=
"s2">.postln
</span></p>
409 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>};
</p>
410 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
411 <p class=
"p11"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
412 <p class=
"p11"><span class=
"Apple-tab-span"> </span>}
</p>
413 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>
414 <p class=
"p11"><span class=
"Apple-tab-span"> </span>a = MyClass();
</p>
415 <p class=
"p11"><span class=
"Apple-tab-span"> </span>a.someMethodThatDoesNotExist
</p>
416 <p class=
"p10"><span class=
"Apple-tab-span"> </span></p>